package com.east.sng.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author east
 * @date: 2021/1/4
 * @Description: my shiro integration spring configuration
 **/
@Configuration
public class ShiroConfig {

    /**
     * 创建shiro 生命周期处理器
     * @return
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 创建shiro拦截器工厂bean
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(securityManager);
        //设置内置的过滤拦截
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/user/confirmUsername","anon");
        filterMap.put("/favicon.ico","anon");
        filterMap.put("/register","anon");
        filterMap.put("/captcha","anon");
        filterMap.put("/login","anon");
        filterMap.put("/logout","anon");
        filterMap.put("/success","anon");
        filterMap.put("/images/**","anon");
        filterMap.put("/css/**","anon");
        filterMap.put("/js/**","anon");
        filterMap.put("/**","authc");
        bean.setFilterChainDefinitionMap(filterMap);
        //设置登录页面
        bean.setLoginUrl("/login");
        //设置登录成功页面
        bean.setSuccessUrl("/index");
        return bean;
    }

    /**
     * 创建安全管理器
     * @param userRealm
     * @return
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联Realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }


    /**配置shiro的session管理器
     * @return
     */
    @Bean(name = "sessionManager")
    public DefaultWebSessionManager getDefaultWebSessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置session过期时间
        sessionManager.setGlobalSessionTimeout(60*60*1000);
        return sessionManager;
    }

    /**
     * 通过SpringAOP开启Shiro的注解
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

    /**
     * 开启 shiro aop注解支持
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    /**
     * 创建custom user AuthorizingRealm
     * @return
     */
    @Bean(name = "userRealm")
    public UserRealm getUserRealm(){
        UserRealm realm = new UserRealm();
        //设置散列算法
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("md5");
        //设置散列次数
        matcher.setHashIterations(3);
        //设置加密处理器
        realm.setCredentialsMatcher(matcher);
        return realm;
    }

    /**
     * 创建ShiroDialect 用于整合shiro和thymeleaf
     * @return
     */
    @Bean
    public ShiroDialect getShiroDialect(){
         return new ShiroDialect();
    }

}
